import { InputState } from "./editor-core";

const insertAfter = (newElement: HTMLElement, targetElement: HTMLElement) => {
  var parent = targetElement.parentElement!;
  if(parent.lastChild == targetElement) {
    parent.appendChild(newElement);
  } else {
      parent.insertBefore(newElement, targetElement.nextSibling);
  }
}

export interface DomController {
  /**
   * 将 DOM 添加到其他 DOM 后
   * @param targetDom 目标 DOM
   */
  appendTo(targetDom: HTMLElement): void;
  
  /**
   * 将 DOM 添加到其他 DOM 的子元素中
   * @param targetDom 目标 DOM
   */
  appendChildTo(targetDom: HTMLElement): void;
  
  /**
   * 移除 DOM
   */
  remove(): void;
  
  /**
   * 获取最后一个 DOM
   */
  getLastDom(): HTMLElement;
  
  /**
   * 获取需要聚焦的 DOM
   */
  getMainDom(): HTMLElement;

  /**
   * 查询 DOM 元素
   * @param selector 选择器
   */
  querySelector(selector: string): HTMLElement | null;
}

export class DefaultDomController implements DomController {
  private dom: HTMLElement;

  constructor(dom: HTMLElement) {
    this.dom = dom;
  }

  appendTo(targetDom: HTMLElement): void {
    insertAfter(this.dom, targetDom);
  }

  appendChildTo(targetDom: HTMLElement): void {
    targetDom.appendChild(this.dom);
  }

  remove(): void {
    this.dom.remove();
  }

  getLastDom(): HTMLElement {
    return this.dom;
  }

  getMainDom(): HTMLElement {
    return this.dom;
  }

  querySelector(selector: string): HTMLElement | null {
    return this.dom.querySelector(selector);
  }
}

export class NextLineDomController implements DomController {
  private br: HTMLBRElement;
  private dom: HTMLElement;

  constructor(br: HTMLBRElement, dom: HTMLElement) {
    this.br = br;
    this.dom = dom;
  }

  appendTo(targetDom: HTMLElement): void {
    insertAfter(this.dom, targetDom);
    insertAfter(this.br, targetDom);
  }

  appendChildTo(targetDom: HTMLElement): void {
    targetDom.appendChild(this.br);
    targetDom.appendChild(this.dom);
  }

  remove(): void {
    this.br.remove();
    this.dom.remove();
  }

  getLastDom(): HTMLElement {
    return this.dom;
  }

  getMainDom(): HTMLElement {
    return this.dom;
  }

  querySelector(selector: string): HTMLElement | null {
    return this.dom.querySelector(selector);
  }
}

export class InputDomController implements DomController {
  private dom: HTMLElement;
  private inputState: InputState;


  constructor(inputState: InputState, dom: HTMLElement) {
    this.inputState = inputState;
    this.dom = dom;
  }

  appendTo(targetDom: HTMLElement): void {
    insertAfter(this.dom, targetDom);
  }

  appendChildTo(targetDom: HTMLElement): void {
    targetDom.appendChild(this.dom);
  }

  remove(): void {
    this.inputState.removing = true;
    this.dom.remove();
  }

  getLastDom(): HTMLElement {
    return this.dom;
  }

  getMainDom(): HTMLElement {
    return this.dom;
  }

  querySelector(selector: string): HTMLElement | null {
    return this.dom.querySelector(selector);
  }
} 